import os
import shutil
from datetime import datetime
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from config.constants import driver_path, chrome_path
from utils.browser_utils import init_chrome_browser


class DatabaseBackupTool:
    """
    数据库备份工具类
    功能：自动登录系统，下载数据库备份文件，并管理备份文件
    """

    def __init__(self, download_dir, backup_dir, log_dir='logs'):
        """
        初始化备份工具
        :param download_dir: 下载目录路径
        :param backup_dir: 备份目录路径
        :param log_dir: 日志目录路径
        """
        self.download_dir = download_dir
        self.backup_dir = backup_dir
        self.log_dir = log_dir
        self.log_file = os.path.join(log_dir, 'backup.log')

        # 确保目录存在
        os.makedirs(backup_dir, exist_ok=True)
        os.makedirs(log_dir, exist_ok=True)

        # 初始化浏览器
        self.driver = init_chrome_browser(
            chrome_path=chrome_path,
            driver_path=driver_path,
            # download_dir=download_dir,  # 设置下载目录
            detach=True  # 保持浏览器打开
        )

    def download_database_backup(self):
        """
        执行数据库备份下载操作
        """
        backup_time = datetime.now()
        time_str = backup_time.strftime('%Y_%m_%d_%H%M')
        log_entry = f"\n=== 数据库备份开始于 {backup_time.strftime('%Y-%m-%d %H:%M:%S')} ===\n"

        try:
            # 启动浏览器
            self.driver.get("https://47.122.30.27:33023/5f40ca64")
            self.driver.maximize_window()

            # 点击高级
            self.driver.find_element(By.XPATH, "/html/body/div/div[2]/button[3]").click()
            # 进入
            self.driver.find_element(By.XPATH, "/html/body/div/div[3]/p[2]/a").click()
            # 输入用户名
            self.driver.find_element(By.XPATH,
                                     "/html/body/div[1]/div/div/aside[3]/div/div[2]/div[1]/div/input").send_keys(
                "8codkm1r")
            # 输入密码
            self.driver.find_element(By.XPATH,
                                     "/html/body/div[1]/div/div/aside[3]/div/div[2]/div[2]/div/input").send_keys(
                "69a377d2")
            # 点击登录
            self.driver.find_element(By.XPATH,
                                     "/html/body/div[1]/div/div/aside[3]/div/div[2]/div[5]/div/button").click()

            # 点击数据库
            try:
                backupButton = WebDriverWait(self.driver, 10).until(
                    EC.element_to_be_clickable(
                        (By.XPATH, "/html/body/section/aside/section/div[2]/div/div/div[1]/div/ul/li[4]/a/span"))
                )
                backupButton.click()
                log_entry += "成功进入数据库页面\n"
            except Exception as e:
                log_entry += f"进入数据库页面失败: {str(e)}\n"
                raise

            # 点击备份
            try:
                radiobutton = WebDriverWait(self.driver, 10).until(
                    EC.element_to_be_clickable((By.XPATH,
                                                "/html/body/section/section/section/div[1]/div/div[2]/div["
                                                "2]/div/div/div[2]/div/div[2]/div/div[3]/table/tbody/tr[2]/td["
                                                "6]/div/div/div/span[1]"))
                )
                radiobutton.click()
                log_entry += "成功点击备份按钮\n"
            except Exception as e:
                log_entry += f"点击备份按钮失败: {str(e)}\n"
                raise

            # 点击下载
            try:
                download_button = WebDriverWait(self.driver, 15).until(
                    EC.element_to_be_clickable((By.XPATH,
                                                "/html/body/div[2]/div/div[2]/div[2]/div/div[1]/div/div[2]/div["
                                                "1]/div/div[2]/div/div[4]/div[2]/table/tbody/tr[1]/td["
                                                "7]/div/div/div/span[2]"))
                )
                download_button.click()
                log_entry += "成功点击下载按钮\n"
            except Exception as e:
                log_entry += f"点击下载按钮失败: {str(e)}\n"
                raise

            log_entry += f"=== 数据库备份下载完成 ===\n"
            self._write_log(log_entry)
            print("数据库备份下载完成！")

            # 备份下载的文件
            self.backup_downloaded_file(time_str)

        except Exception as e:
            error_msg = f"数据库备份过程中出错: {str(e)}\n"
            self._write_log(error_msg)
            print(error_msg)
            raise

    def backup_downloaded_file(self, time_str):
        """
        备份下载的文件到指定目录
        :param time_str: 时间字符串用于命名备份文件夹
        """
        log_entry = f"\n=== 开始备份下载文件 {datetime.now().strftime('%Y-%m-%d %H:%M:%S')} ===\n"

        try:
            # 获取下载目录中最新的文件
            files = []
            for filename in os.listdir(self.download_dir):
                filepath = os.path.join(self.download_dir, filename)
                if os.path.isfile(filepath):
                    mtime = os.path.getmtime(filepath)
                    files.append((mtime, filename, filepath))

            if not files:
                log_entry += "下载目录中没有文件可备份\n"
            else:
                # 找到最新的文件
                files.sort(reverse=True)  # 按修改时间降序排列
                latest_mtime, latest_filename, latest_filepath = files[0]

                # 创建以时间命名的备份文件夹
                backup_folder_name = f"{time_str}_backup"
                target_folder = os.path.join(self.backup_dir, backup_folder_name)
                os.makedirs(target_folder, exist_ok=True)

                # 设置目标路径
                target_path = os.path.join(target_folder, latest_filename)

                # 执行备份
                shutil.copy2(latest_filepath, target_path)
                log_entry += f"已备份最新文件: {latest_filename} 到文件夹 {backup_folder_name}/\n"

            log_entry += f"=== 文件备份完成 ===\n"
            self._write_log(log_entry)
            print("下载文件备份完成！")

        except Exception as e:
            error_msg = f"文件备份过程中出错: {str(e)}\n"
            self._write_log(error_msg)
            print(error_msg)
            raise

    def _write_log(self, message):
        """
        写入日志文件
        :param message: 要记录的日志信息
        """
        with open(self.log_file, 'a', encoding='utf-8') as f:
            f.write(message)


# 使用示例
if __name__ == "__main__":
    # 配置目录
    DOWNLOAD_DIR = "C:/Users/Administrator/Downloads"  # 替换为你的下载目录
    BACKUP_DIR = "D:/LvHua/数据库备份"  # 替换为你的备份目录
    LOG_DIR = "logs"  # 日志目录

    try:
        # 创建备份工具实例并执行备份
        backup_tool = DatabaseBackupTool(
            download_dir=DOWNLOAD_DIR,
            backup_dir=BACKUP_DIR,
            log_dir=LOG_DIR
        )
        backup_tool.download_database_backup()
    except Exception as e:
        print(f"备份过程中发生错误: {str(e)}")